﻿using System;
using System.Collections.Generic;

using VSTalk.Engine.Core.Context;
using VSTalk.Engine.Core.Feed;
using VSTalk.Model;
using VSTalk.Tools;

namespace VSTalk.Engine.Core.ChatSession
{
    public class ChatSessionFactory : IChatSessionFactory, IListener, IDisposable
    {
        private readonly IDictionary<Interlocutor, InterlocutorChatSession> _sessions = new Dictionary<Interlocutor, InterlocutorChatSession>();
        
        private ISubscription _interlocutorUnit;

        public IModelContext ModelContext
        {
            get { return AppServices.Get<IModelContext>(); }
        }

        public IMessageFeed MessageFeed
        {
            get { return AppServices.Get<IMessageFeed>(); }
        }

        public ChatSessionFactory()
        {
            StartListen();
        }

        public IInterlocutorChatSession Create(Interlocutor interlocutor)
        {
            if (_sessions.ContainsKey(interlocutor))
            {
                return _sessions[interlocutor];
            }
            var session = new InterlocutorChatSession(interlocutor);
            _sessions.Add(interlocutor, session);
            MessageFeed.Subscribe(session);
            return session;
        }

        public void StartListen()
        {
            _interlocutorUnit = ModelContext.Interlocutors.HandleRemoveChanges(removed: interlocutor =>
            {
                if (!_sessions.ContainsKey(interlocutor)) return;
                var target = _sessions[interlocutor];
                MessageFeed.Unsubscribe(target);
                _sessions.Remove(interlocutor);
            });
        }

        public void StopListen()
        {
            _interlocutorUnit.Unsubscribe();
            foreach (var session in _sessions)
            {
                MessageFeed.Unsubscribe(session.Value);
            }
        }

        public void Dispose()
        {
            StopListen();
        }
    }
}